<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <!-- support for mobile touch devices -->
  <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">

  <link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
  <link href="../dialogPolyfill.css" rel="stylesheet">
  <link href="../cornerstone.min.css" rel="stylesheet">
</head>
<body>
  <div class="container">
    <div class="page-header">
      <h1>
        Layered Image Stacks Example
      </h1>
      <p>
        This page contains an example of adding two stacks as layers. Here we show a PET stack overlaid on a CT stack. The developer defines a custom function for determining which image in the stack to show depending on the base layer image.
      </p>
      <a href="../index.html">Go back to the Examples page</a>
    </div>

    <div class="row">

      <div class="col-xs-12 col-sm-9">
        <div style="width:512px;height:512px;position:relative;display:inline-block;"
            oncontextmenu="return false"
            class='cornerstone-enabled-image'
            unselectable='on'
            onselectstart='return false;'
            onmousedown='return false;'>
          <div id="dicomImage"
            style="width:512px;height:512px;top:0px;left:0px; position:absolute;">
          </div>
        </div>
      </div>
      <div class="col-xs-12 col-sm-3">
            <div style="margin-bottom: 15px;">
                <label for="syncViewports"> Sync Viewports
                    <input name="syncViewports" type="checkbox" checked>
                </label>
            </div>

            <label for="layers">Select active layer</label>
            <select name="layers" id="layers" size="2" style="width: 100%; min-width: 150px;"></select>
            <div id="properties" style="width: 100%; min-width: 150px; margin-top: 15px;">
                <label>Layer Properties</label>
                <div style="width: 100%; padding: 5px 5px 5px 10px;">
                    <div style="margin-bottom: 15px;">
                        <label for="visible"> Visible
                            <input name="visible" type="checkbox" checked>
                        </label>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <label for="colormaps"> Colormap </label>
                        <select id="colormaps" style="width:100%">
                            <option value="">None</option>
                        </select>
                    </div>
                    <div style="margin-bottom: 15px;">
                        <label for="imageOpacity"> Opacity</label>
                        <input id="imageOpacity" type="range" class="range" min=0 max=1 step=0.1 value=0>
                    </div>
                </div>
            </div>
        </div>
    </div>
  </div>
</body>

<!-- include the cornerstone library -->
<script src="../cornerstone.js"></script>

<script src="../cornerstoneMath.min.js"></script>

<!-- include the cornerstone tools library -->
<script src="../../dist/cornerstoneTools.js"></script>
<script>window.cornerstoneTools || document.write('<script src="https://unpkg.com/cornerstone-tools">\x3C/script>')</script>

<!-- include special code for these examples which provides images -->
<script src="../petctImageIdLoader.js"></script>
<script src="../petctMetaDataProvider.js"></script>

<script>
  var element = document.getElementById('dicomImage');

  // Select the right layer in the dropdown
  function updateSelectedLayer(layerId) {
      var layers = document.getElementById('layers');
      var currentLayerId = layers.value;

      if(currentLayerId !== layerId) {
          layers.value = layerId;
          layers.trigger('change');
      }
  }

  // Listen to `change` event to set the selected layer as active
  document.getElementById('layers').addEventListener('change', function(event) {
      var layerId = event.currentTarget.value;
      cornerstone.setActiveLayer(element, layerId);
  });

  // Listen to `change` event to activate/deactivate the viewport synchronization
  document.querySelector('input[name=syncViewports]').addEventListener('change', function(event) {
      var enabledElement = cornerstone.getEnabledElement(element);
      enabledElement.syncViewports = event.currentTarget.checked;
      cornerstone.updateImage(element);
  });

  document.getElementById('colormaps').addEventListener('change', function() {
      var layer = cornerstone.getActiveLayer(element);
      layer.viewport.colormap = document.getElementById('colormaps').value;
      cornerstone.updateImage(element);
  });

  // Listen to `change` event to update the opacity of the active layer
  document.getElementById('imageOpacity').addEventListener('change', function(event) {
      var layer = cornerstone.getActiveLayer(element);
      layer.options.opacity = parseFloat(event.currentTarget.value);
      cornerstone.updateImage(element);
  });

  // Listen to `change` event to update the visibility of the active layer
  document.querySelector('input[name=visible]').addEventListener('change', function(event) {
      var layer = cornerstone.getActiveLayer(element);
      layer.options.visible = event.currentTarget.checked;
      cornerstone.updateImage(element);
  });

  // This event will be called every time a layer is added through cornerstone.addLayer
  // The layer is added to the dropdown to make it possible to select and interact with it
  element.addEventListener('cornerstonelayeradded', function(e) {
      var eventData = e.detail;
      var layer = cornerstone.getLayer(eventData.element, eventData.layerId);
      var layers = document.getElementById('layers');
      var layerOption = document.createElement("OPTION");
      layerOption.value = layer.layerId;
      layerOption.textContent = layer.options.name;

      // Set the layer as selected in case its the the first layer to be added
      if(layers.children.length === 0) {
          layerOption.selected = true;
      }

      layers.appendChild(layerOption);
  });

  // This event will be called every time cornerstone.setActiveLayer is called
  // We need to load the layer properties and update the selected layer in the dropdown
  element.addEventListener('cornerstoneactivelayerchanged', function(e) {
      var eventData = e.detail;
      var layer = cornerstone.getActiveLayer(element);
      var colormap = layer.viewport.colormap || '';
      var opacity = layer.options.opacity == null ? 1 : layer.options.opacity;
      var visible = layer.options.visible !== false ? 1 : 0;

      // Restore all properties for the active layer
      document.getElementById('imageOpacity').value = opacity;
      document.querySelector("input[name=visible]").checked = !!visible;
      document.getElementById('colormaps').value = colormap;

      updateSelectedLayer(eventData.layerId);
  });

  // Populate colormap dropdown with all the default ones
  function fillColormapsList() {
      var dropdown = document.getElementById('colormaps');
      var colormapsList = cornerstone.colors.getColormapsList();

      var addOption = function(id, name) {
        var option = document.createElement("OPTION");
        option.value = id;
        option.textContent = name;

        dropdown.appendChild(option);
      };

      colormapsList.forEach(function(colormapItem) {
          addOption(colormapItem.id, colormapItem.name);
      });
  }

  cornerstone.enable(element);

  var ctStack = {
    imageIds: ['ct://1', 'ct://2'],
    currentImageIdIndex: 0,
    options: {
      opacity: 1,
      visible: true,
      name: 'CT'
    }
  };

  var petStack = {
    imageIds: ['pet://1', 'pet://2'],
    currentImageIdIndex: 0,
    options: {
      opacity: 0.7,
      visible: true,
      viewport: {
        colormap: 'jet',
        voi: {
          windowWidth: 30,
          windowCenter: 17
        }
      },
      name: 'PET'
    }
  };

  // Select a renderer and apply the specified options
  var renderer = new cornerstoneTools.stackRenderers.FusionRenderer();
  renderer.findImageFn = function(imageIds, targetImageId) {
    var minDistance = 1;
    var targetImagePlane = cornerstone.metaData.get('imagePlaneModule', targetImageId);
    var imagePositionZ = targetImagePlane.imagePositionPatient[2];

    var closest;
    imageIds.forEach(function(imageId) {
      var imagePlane = cornerstone.metaData.get('imagePlaneModule', imageId);
      var imgPosZ = imagePlane.imagePositionPatient[2];
      var distance = Math.abs(imgPosZ - imagePositionZ);
      if (distance < minDistance) {
        minDistance = distance;
        closest = imageId;
      }
    });

    return closest;
  };

  // Create a stack from the image object array
  cornerstone.loadAndCacheImage(ctStack.imageIds[0]).then(image => {
      cornerstone.displayImage(element, image);

      cornerstoneTools.addStackStateManager(element, ['stack']);
      cornerstoneTools.addToolState(element, 'stack', ctStack);
      cornerstoneTools.addToolState(element, 'stack', petStack);
      cornerstoneTools.addToolState(element, 'stackRenderer', renderer);

      renderer.render(element);

      cornerstoneTools.mouseInput.enable(element);
      cornerstoneTools.mouseWheelInput.enable(element);
      cornerstoneTools.wwwc.activate(element, 1);
      cornerstoneTools.pan.activate(element, 2);
      cornerstoneTools.zoom.activate(element, 4);
      cornerstoneTools.stackScrollWheel.activate(element);
  });

  fillColormapsList();
</script>
</html>
